﻿using System;
using TwlPhy;
using UnityPool;
using UnityEngine;
using TwlNet;
using pb;
using TwlAction;

public class AppStart : MonoBehaviour
{
    private int roleId = -1;
    public bool useNet = false;
    private string ip = "192.168.0.107";
    private string port = "8007";
    private string str = "连接状态: {0}";
    /// <summary>
    /// 初始化
    /// </summary>
    private void Awake()
    {
        ManifestMgr.Init();
        AtlasMgr.Instance.Init();
        LoadThread.Instance.init();
        FrameUpdate.Instance.init();
        LevelMgr.Instance.init();
        if (useNet)
        {
            //GameSocket.Instance.run("192.168.0.107", "8007");
            GameSocket.Instance.run(ip, port);
            SocketThread.initilize(processPBMsg);
        }
        roleId = MathUtils.UniqueID;
    }


    //处理写协议 1帧30个包
    private void processPBMsg()
    {
        for (int i = 0; i < 30; i++)
        {
            PBMessage pbs = GameSocket.Instance.getMsg();
            if (pbs != null)
            {
                callLuaNetFun(pbs);
            }
            else
            {
                break;
            }
        }
    }

    /// <summary>
    /// cmd 101 请求创建角色
    /// cmd 102 创建角色返回
    /// cmd 103 客户端同步移动包
    /// cmd 104 服务器同步移动包
    /// cmd 105 通知实体状态
    /// 技能协议
    /// cmd 201 客户端释放技能请求
    /// cmd 202 服务器广播释放技能
    /// cmd 203 客户端伤害检测请求
    /// cmd 204 服务器广播伤害检测
    /// </summary>
    /// <param name="pb"></param>
    private void callLuaNetFun(PBMessage pb)
    {
        //Debug.LogError("收到消息 cmd " + pb.cmd);
        switch (pb.cmd)
        {
            case 102:
                PlayerInfoMsg infoMsg = ProtobufSerializer.DeSerialize<PlayerInfoMsg>(pb.data);
                onPlayerCreateMsg(infoMsg);
                break;
            case 104:
                SyncPlayerPosResp posMsg = ProtobufSerializer.DeSerialize<SyncPlayerPosResp>(pb.data);
                onPlayerMoveMsg(posMsg);
                break;
            case 105:
                PlayerLivingStateMsg stateMsg = ProtobufSerializer.DeSerialize<PlayerLivingStateMsg>(pb.data);
                onPlayerLivingStateMsg(stateMsg);
                break;
            case 202:
                SkillBroadcastMsg skillMsg = ProtobufSerializer.DeSerialize<SkillBroadcastMsg>(pb.data);
                onSkillBroadcastMsg(skillMsg);
                break;
            case 204:
                SkillBroadHitMsg hitMsg = ProtobufSerializer.DeSerialize<SkillBroadHitMsg>(pb.data);
                onHitBroadcastMsg(hitMsg);
                break;
        }
    }

    //实体创建
    private void onPlayerCreateMsg(PlayerInfoMsg msg)
    {
        RoleData roleData = Pool.PoolMgr.Instance.getData<RoleData>();
        roleData.uid = msg.playerId;
        roleData.nickName = msg.name;
        roleData.resName = msg.resName;
        roleData.pos = new TwlPhy.Vector2(msg.pos.x * 0.001f, msg.pos.y * 0.001f);
        roleData.moveBox = new TwlPhy.Vector3(msg.moveBox.x * 0.001f, msg.moveBox.y * 0.001f, msg.height * 0.001f);
        roleData.speed = msg.speed * 0.001f;
        roleData.jumpSpeed = msg.jumpSpeed * 0.001f;
        roleData.scale = new TwlPhy.Vector3(msg.scale.x * 0.001f, msg.scale.y * 0.001f, msg.scale.z * 0.001f);
        roleData.roleType = (Role_Type)(msg.roleType);
        roleData.hitBox = new TwlPhy.Vector3(msg.hitBox.x * 0.001f, msg.hitBox.y * 0.001f,3.5f);
        roleData.lookFlag = msg.lookFlag == 1 ? LookFlag.Right : LookFlag.Left;
        Debug.Log("msg.playerId: " + msg.playerId);
        if (roleData.roleType == Role_Type.MainPlayer) {
            EntityMgr.Instance.mainRoleId = roleData.uid;
            EntityMgr.createRole<MainPlayer>(roleData);
        }        
        else
            EntityMgr.createRole<DynamicEntity>(roleData);
    }

    //玩家移动同步
    private void onPlayerMoveMsg(SyncPlayerPosResp posMsg)
    {
        //Logger.logError("posMsg.playerId  " + posMsg);
        BaseEntity role = EntityMgr.getRole<BaseEntity>(posMsg.playerId);
        if (role != null && role.UID != EntityMgr.Instance.mainRoleId)
        {
            if (posMsg.speed * 1000 <= 0)
            {
                if (role.Flag == FSM_Flag.Run)
                {
                    role.transFsm(FSM_Flag.Idle);
                }
            }
            else
            {
                FSMArgs args = new FSMArgs();
                args.data = posMsg;
                role.transFsm(FSM_Flag.Run, args);
            }
        }
    }

    //实体状态同步 1移除
    private void onPlayerLivingStateMsg(PlayerLivingStateMsg msg)
    {
        if (msg.state == 1)
        {
            EntityMgr.removeRole(msg.playerId);
        }
    }

    //服务器同步技能
    private void onSkillBroadcastMsg(SkillBroadcastMsg msg)
    {
        BaseEntity role = EntityMgr.getRole<BaseEntity>(msg.playerId);
        if (role != null)//&& role.UID != EntityMgr.Instance.mainRoleId
        {
            int skillId = msg.skillId;
            //FSMArgs args = Pool.PoolMgr.Instance.getData<FSMArgs>();
            //args.data = SkillConfigHelper.Instance.getConfig(skillId);
            //role.transFsm(FSM_Flag.Skill, args);
            ActionData actionData = new ActionData();
            actionData.actionId = msg.skillId;
            actionData.actionGuid = MathUtils.UniqueID;//应该服务器推送
            actionData.ownerId = msg.playerId;
            actionData.ownerPos = new TwlPhy.Vector3(msg.pos.x, msg.pos.y, msg.pos.z);//*0.001
            ActionMgr.Instance.create<BaseAction>(actionData);
        }
    }

    //伤害包广播 包里面没有带伤害todo
    private void onHitBroadcastMsg(SkillBroadHitMsg msg)
    {
        for (int i = 0; i < msg.hiters.Count; i++)
        {
            long roleId = msg.hiters[i];
            BaseEntity role = EntityMgr.getRole<BaseEntity>(roleId);
            if (role != null)
            {
                int skillId = msg.skillId;
                FSMArgs args = Pool.PoolMgr.Instance.getData<FSMArgs>();
                args.cfgId = msg.hitId;
                args.data = new TwlPhy.Vector3(msg.pos.x, msg.pos.y, msg.pos.z);
                role.transFsm(FSM_Flag.Hit, args, true);
                //hp todo
            }
        }
    }

    private void createRoleByNet()
    {
        int HEAD_LEN = 18;//包头长度
        short HEAD_FIX = 0x71ab;
        long roleId = EntityMgr.Instance.mainRoleId;
        GetPlayerInfoMsg msg = new GetPlayerInfoMsg();
        msg.playerId = roleId;
        byte[] data = ProtobufSerializer.Serialize<pb.GetPlayerInfoMsg>(msg);
        int len = data.Length;
        ByteBuffer buffer = ByteBuffer.Allocate(len + HEAD_LEN);
        buffer.WriteShort(HEAD_FIX);
        buffer.WriteShort((short)(HEAD_LEN + len));
        buffer.WriteShort(101);
        buffer.WriteLong(roleId);
        buffer.WriteInt(0);
        buffer.WriteBytes(data);
        GameSocket.Instance.Send(buffer);
        Debug.LogError("请求服务器创建玩家");
    }

    private void createRoleByClient()
    {
        //创建一个可以控制的主角
        RoleData roleData = Pool.PoolMgr.Instance.getData<RoleData>();
        roleData.uid = roleId;
        roleData.pos.x = -2;
        roleData.speed = 6;
        roleData.moveBox = new TwlPhy.Vector3(2, 0.4f,0f);
        roleData.hitBox = new TwlPhy.Vector3(1f, 1f,3.5f);
        roleData.scale = new TwlPhy.Vector3(0.5f, 0.5f, 1);
        roleData.nickName = "CocoTang";
        roleData.resName = @"AssetBundle\Prefabs\model\rolemine\role_mine";
        roleData.roleType = Role_Type.MainPlayer;
        EntityMgr.createRole<MainPlayer>(roleData);

        //创建一个怪@"AssetBundle\Prefabs\model\RoleWarrior\role_warrior";
        RoleData roleData2 = Pool.PoolMgr.Instance.getData<RoleData>();
        roleData2.uid = MathUtils.UniqueID;
        roleData2.nickName = "奥巴马";
        roleData2.resName = @"AssetBundle\Prefabs\model\rolemine\role_mine";
        roleData2.roleType = Role_Type.Monster;
        roleData2.pos.x = 3;
        roleData2.speed = 6;
        roleData2.moveBox = new TwlPhy.Vector3(2, 0.4f, 0f);
        roleData2.hitBox = new TwlPhy.Vector3(1f, 1f, 3.5f);
        roleData2.scale = new TwlPhy.Vector3(0.5f, 0.5f, 1);
        roleData2.lookFlag = LookFlag.Left;
        EntityMgr.createRole<Monster>(roleData2);
    }


    private void OnApplicationQuit()
    {
        Logger.logError("OnApplicationQuit");
        GameSocket.Instance.onDispose();
    }

    private void OnGUI()
    {
        GUILayout.BeginVertical();
        GUI.backgroundColor = useNet ? Color.green : Color.red;
        if (GUILayout.Button(new GUIContent("是否使用网络连接"), GUILayout.Height(30)))
        {
            useNet = !useNet;
            EntityMgr.removeAll();
        }
        GUI.backgroundColor = Color.black;
        GUILayout.Space(20);
        GUILayout.BeginHorizontal();
        string lbl = string.Format(str, GameSocket.Instance.isConnect() ? "已连接" : "已断开");
        GUIStyle style = new GUIStyle();
        //style.fontSize = 22;
        style.alignment = TextAnchor.MiddleCenter;
        GUILayout.Label(lbl, GUILayout.Height(30));
        if (GUILayout.Button("尝试连接", GUILayout.Height(30)))
        {
            if (!GameSocket.Instance.isConnect())
            {
                GameSocket.Instance.run(ip, port);
                SocketThread.initilize(processPBMsg);
            }
        }
        GUILayout.EndHorizontal();
        //ip
        GUILayout.BeginHorizontal();
        GUILayout.Label("IP : ", GUILayout.Height(30), GUILayout.Width(15));
        GUILayout.Space(10);
        ip = GUILayout.TextField(ip, GUILayout.Height(30));
        GUILayout.EndHorizontal();
        //port
        GUILayout.Label(port);
        //其他按钮
        GUILayout.Space(30);
        GUILayout.BeginHorizontal();
        if (GUILayout.Button("创建主角", GUILayout.Width(160), GUILayout.Height(50))) {
                if (!useNet)
                {
                    if (EntityMgr.getRole<MainPlayer>(roleId) == null)
                        createRoleByClient();
                }
                else
                {
                    createRoleByNet();
                }
        }
        GUILayout.EndHorizontal();
        GUILayout.EndVertical();

    }
}

